<template>
  <div class="certification">
    <!-- 实名认证结构 -->
    <el-card class="box-card">
      <!-- 卡片的头部区域 -->
      <template #header>
        <div class="card-header">
          <h1>实名信息</h1>
        </div>
      </template>
      <!-- 卡片的主体内容区域 -->
      <!-- 提示区域 -->
      <div class="tip">
        <el-icon><InfoFilled /></el-icon>
        <p>完成实名认证之后才能添加就诊人,正常进行挂号,为了不影响后续步骤,建议提前实名认证。</p>
      </div>
      <!-- 已完成实名认证的结构 -->
      <el-descriptions
        class="margin-top"
        :column="1"
        border
        style="margin-top: 20px"
        v-if="userInfo.authStatus == 1"
      >
        <el-descriptions-item width="10px">
          <template #label>
            <div class="cell-item" align="center">用户姓名</div>
          </template>
          {{ userInfo.name }}
        </el-descriptions-item>
        <el-descriptions-item width="10px">
          <template #label>
            <div class="cell-item" align="center">证件类型</div>
          </template>
          {{ userInfo.certificatesType == "10" ? "身份证" : "户口本" }}
        </el-descriptions-item>
        <el-descriptions-item width="10px">
          <template #label>
            <div class="cell-item" align="center">证件号码</div>
          </template>
          {{ userInfo.certificatesNo }}
        </el-descriptions-item>
      </el-descriptions>
      <!-- 未完成实名认证的结构 -->
      <el-form v-else style="width: 50%; margin: 20px auto" :model="params" :rules="rules" ref="form">
        <el-form-item label="用户姓名" prop="name">
          <el-input placeholder="请输入用户姓名" v-model="params.name"></el-input>
        </el-form-item>
        <el-form-item label="证件类型" prop="certificatesType">
          <el-select placeholder="请输入证件类型" v-model="params.certificatesType">
            <el-option
              :label="type.name"
              :value="type.value"
              v-for="(type, index) in typeArr"
              :key="index"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="证件号码" prop="certificatesNo">
          <el-input placeholder="请输入证件号码" v-model="params.certificatesNo"></el-input>
        </el-form-item>
        <el-form-item label="上传证件" prop="certificatesUrl">
          <el-upload list-type="picture-card" label="上传证件" ref="upload"
          :on-success="successUploadHandler"
          :on-exceed="exceedNumberHandler"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemovePicture"
          :limit="1"
          action="/api/oss/file/fileUpload?fileHost=userAuah">
            <img
              style="width: 100%"
              src="../../../assets/images/auth_example.png"/>
          </el-upload>
          <el-dialog v-model="dialogVisible">
              <img w-full v-if="params.certificatesUrl"  style="width: 100%;height: 100%;" :src="params.certificatesUrl" alt="图片预览" />
          </el-dialog>
        </el-form-item>
        <el-form-item style="margin-left: 70px">
          <el-button type="primary" @click="submit">提交</el-button>
          <el-button @click="reset">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { InfoFilled } from "@element-plus/icons-vue";
import { nextTick, onMounted, reactive, ref } from "vue";
// 引入API
import { reqUserInfo, reqCertificatesType, reqUserAuah } from "@/api/user/index";
// 引入ts类型
import { UseringoResponseData, CertificatesTypeArr, userAuahData } from "@/api/user/type";
import { ElMessage } from "element-plus";

// 存储用户信息
let userInfo = ref<any>({});
// 存储证件类型
let typeArr = ref<CertificatesTypeArr>([]);
// 控制预览图片对话框的显示与隐藏
let dialogVisible = ref<boolean>(false)
// 获取upload实例
let upload = ref<any>()
// 获取表单的实例
let form = ref<any>()
// 收集用户认证表单的数据
let params = reactive<userAuahData>({
    "certificatesNo": '',
    "certificatesType": '',
    "certificatesUrl": '',
    "name": ''
})
// 组件挂载完毕获取用户信息
onMounted(() => {
  // 获取用户信息
  getUserInfo();
  // 获取证件类型
  getType();
});
// 封装一个方法获取用户信息
const getUserInfo = async () => {
  const result: UseringoResponseData = await reqUserInfo();
  if (result.code == 200) {
    // 存储用户信息
    userInfo.value = result.data;
  }
};
// 获取证件类型的方法
const getType = async () => {
  const result: any = await reqCertificatesType();
  if (result.code == 200) {
    // 存储证件类型
    typeArr.value = result.data;
  }
};
// 照片墙超出图片数量的钩子
const exceedNumberHandler = ()=>{
    ElMessage({
        type:'error',
        message:'最多上传一张图片！'
    })
}
// 成功上传图片的钩子
const successUploadHandler = (response: any)=>{
    // 成功上传图片之后要清除上一次的验证提示
    form.value.clearValidate('certificatesUrl');
    console.log(response);
    // 为图片地址赋值，就是上传图片成功会返回一个url地址
    params.certificatesUrl = response.data
}
// 预览图片的回调
const handlePictureCardPreview = ()=>{
    // 显示预览图片的对话框
    dialogVisible.value = true
}
// 删除图片的钩子
const handleRemovePicture = ()=>{
    // 把图片地址置为空
    params.certificatesUrl = ''
}
// 点击重置按钮的回调
const reset = ()=>{
    // 清除图片数据
    upload.value.clearFiles();
    // 清空数据
    Object.assign(params, {
        "certificatesNo": '',
        "certificatesType": '',
        "certificatesUrl": '',
        "name": ''
    })
    // 清空所有的验证提示
    nextTick(()=>{
        form.value.clearValidate();
    })
    // 刷新组件重置信息
    window.location.reload()
}
// 点击提交按钮的回调
const submit = async ()=>{
    // 在进行后续请求之前要先通过表单验证
    await form.value.validate();
    try{
        // 发请求进行实名认证
       await reqUserAuah(params)
       //提示信息
       ElMessage({
        type:'success',
        message:'实名成功'
       })
    //实名成功之后,重新获取用户信息
    getUserInfo();
    }catch(e){
        ElMessage({
            type:'error',
            message:'实名失败'
        })
    }
}
// 姓名的自定义校验规则
const validatorName = (rule:any,value:any,callBack:any)=>{
    // 中国人姓名的正则表达式
    const reg = /^[\u00B7\u3007\u3400-\u4DBF\u4E00-\u9FFF\uE000-\uF8FF\uD840-\uD8C0\uDC00-\uDFFF\uF900-\uFAFF]+$/;
    if(reg.test(value)){
        callBack();
    }else{
        callBack(new Error('请输入正确的姓名'))
    }
}
// 证件类型的自定义校验方法
const validatorType = (rule: any, value: any, callBack: any)=>{
    if(value=='10'||value=='20'){
        callBack();
    }else{
        callBack(new Error('请选择证件类型'))
    }
}
// 证件号码的自定义校验规则
const validatorNo = (rule: any, value: any, callBack: any)=>{
    // 身份证号的正则表达式
    let sfz = /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/;
    // 户口本的正则表达式
    let hkb = /^\d{9}$/;
    if(sfz.test(value)||hkb.test(value)){
        callBack();
    }else{
        callBack(new Error('请输入正确的证件号码'))
    }
}
// 照片墙图片的自定义校验规则
const validatorUrl = (rule: any, value: any, callBack: any)=>{
    if(value.length){
        callBack();
    }else{
        callBack(new Error('请上传证件照片'))
    }
}
// 实名认证表单的校验规则
const rules = {
    name:[{required:true,trigger:'change',validator: validatorName}],
    certificatesType:[{ required: true, trigger: 'change' , validator: validatorType }],
    certificatesNo:[{ required: true, trigger: 'change', validator: validatorNo }],
    certificatesUrl:[{ required: true, trigger: 'change', validator: validatorUrl }]
}
</script>

<style scoped lang="scss">
.box-card {
  margin-top: 20px;

  .tip {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    color: #7f7f7f;
  }
}
</style>